Inside Macintosh: Sound

| Previous | Chapter contents | Chapter top | Section top | Next |

Looping a Sound Indefinitely

If you install a sampled sound as a voice in a channel and then play the sound using a  freqCmd or freqDurationCmd command that lasts longer than the sound, the sound will ordinarily stop before the end of the time specified by the freqCmd or freqDurationCmd command. Sometimes, however, this might not be what you'd like to have happen. For example, you might have recorded the sound of a violin playing and then stored that sound in a resource so that you could play the sound of a violin at a number of different frequencies. Although you could record the sound so that it is long enough to continue playing through the longest freqCmd or freqDurationCmd command that your application might require, this might not be practical. Fortunately, the Sound Manager provides a mechanism that allows you to repeat sections of sampled sound after the sound has finished playing once completely.

When you use the freqDurationCmd command with a sampled sound as the voice, freqDurationCmd starts at the beginning of the sampled sound. If necessary to achieve the desired duration of sound, the command replays that part of the sound that is between the loop points specified in the sampled sound header. Note that any sound preceding or following the loop points will not be replayed. There must be an ending point for the loop specified in the header in order for freqDurationCmd to work properly.

Listing 27 Looping an entire sampled sound

PROCEDURE MyDoLoopEntireSound (sndHandle: Handle);
VAR
    mySndHeader:        SoundHeaderPtr;             {sound header from resource}
    myTotalBytes:       LongInt;                    {bytes of data to loop}
BEGIN
    mySndHeader := MyGetSoundHeader(sndHandle);
    IF mySndHeader <> NIL THEN
    BEGIN                                           {compute bytes of sound data}
        CASE mySndHeader^.encode OF
            stdSH:                                  {standard sound header}
                WITH mySndHeader^ DO
                    myTotalBytes := mySndHeader^.length;
            extSH:                                  {extended sound header}
                WITH ExtSoundHeaderPtr(mySndHeader)^ DO
                    myTotalBytes := numChannels * numFrames * (sampleSize DIV 8);
            cmpSH:                                  {compressed sound header}
                WITH CmpSoundHeaderPtr(mySndHeader)^ DO
                    myTotalBytes := numChannels * numFrames * (sampleSize DIV 8);
        END;
        WITH mySndHeader^ DO
        BEGIN                                       {set loop points}
            loopStart := 0;                         {start with first byte}
            loopEnd := myTotalBytes - 1;            {end with last byte}
        END;
    END;
END;

Listing 1-27 uses the MyGetSoundHeader function defined in "Obtaining a Pointer to a Sound Header" . Note that the formula for computing the length of a sound depends on the type of sound header. Also, while the formula is the same for both an extended and a compressed sound header, you must write code that differentiates between the two types of sound headers because the sampleSize field is not stored in the same location in both sound headers.


© 1998 Apple Computer, Inc.

| Previous | Chapter contents | Chapter top | Section top | Next |